package com.wind.plugin.openAction;

import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorLocation;
import com.intellij.openapi.fileEditor.FileEditorState;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.ui.components.*;
import com.intellij.ui.table.JBTable;
import com.wind.plugin.openAction.Listener.MyTableModelListener;
import com.wind.plugin.openAction.entity.Action;
import com.wind.plugin.openAction.entity.FlowActions;
import com.wind.plugin.openAction.Listener.CustomFileListener;
import com.wind.plugin.openAction.utils.Util;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

public class CustomTextEditorAi implements FileEditor {

    private static final Logger LOG = Logger.getInstance(CustomTextEditor.class);
    private final Project project;
    private final VirtualFile file;
    private final JPanel panel;
    private final JBTable actionsTable;
    private final DefaultTableModel tableModel;
    private final List<Action> actionConfigs;
    private FlowActions flowActions;
    private final JPanel panelHead;
    private JLabel jLabelBankCode;
    private JLabel jLabelBankType;
    private JLabel jLabelVersion;
    private JLabel jLabelDescription;
    private JTextField jTextFieldBankCode;
    private JTextField jTextFieldBankType;
    private JTextField jTextFieldVersion;
    private JTextField jTextAreaDescription;

    // 标志位，指示文件是否是由程序自动修改的
    private boolean isProgrammaticChange = false;

    public CustomTextEditorAi(Project project, VirtualFile file) {
        this.project = project;
        this.file = file;

        this.actionConfigs = new ArrayList<>();
        panel = new JBPanel(new BorderLayout());
        // 创建表格
        String[] columnNames = {"动作类", "是否发送", "配置类型", "编辑"};
        tableModel = new DefaultTableModel(columnNames, 0);
        actionsTable = new JBTable(tableModel);
        panelHead = new JPanel();
        panelHead.setLayout(new FlowLayout(FlowLayout.LEFT));



        jLabelBankCode = new JBLabel("银行代码");
        jTextFieldBankCode = new JTextField("银行代码");
        JPanel panelBankCode = new JPanel(new FlowLayout(FlowLayout.CENTER));
        panelBankCode.add(jLabelBankCode);
        panelBankCode.add(jTextFieldBankCode);
        panelHead.add(panelBankCode);


        jLabelBankType = new JBLabel("交易类型");
        jTextFieldBankType = new JTextField("交易类型");
        JPanel panelBankType = new JPanel(new FlowLayout(FlowLayout.CENTER));
        panelBankType.add(jLabelBankType);
        panelBankType.add(jTextFieldBankType);
        panelHead.add(panelBankType);


        jLabelVersion = new JBLabel("版本号");
        jTextFieldVersion = new JTextField("版本号");
        JPanel panelVersion = new JPanel(new FlowLayout(FlowLayout.CENTER));
        panelVersion.add(jLabelVersion);
        panelVersion.add(jTextFieldVersion);
        panelHead.add(panelVersion);


        jLabelDescription = new JBLabel("描述");
        jTextAreaDescription = new JTextField("描述");
        JPanel panelDescription = new JPanel(new FlowLayout(FlowLayout.CENTER));
        panelVersion.add(jLabelDescription);
        panelVersion.add(jTextAreaDescription);
        panelHead.add(panelDescription);

        panel.add(panelHead, BorderLayout.NORTH);

        // 注册文件监听器
        registerFileListener();

        // 添加表格模型监听器
        MyTableModelListener modelListener = new MyTableModelListener(this);
        tableModel.addTableModelListener(modelListener);

        panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

        loadFile();
        setUpUI();
    }

    private void addListeners() {

        // 给 JTextField 添加 DocumentListener
        jTextFieldBankType.getDocument().addDocumentListener(new DocumentListener() {
            @Override
            public void insertUpdate(DocumentEvent e) {
                updateLabel();  // 当内容插入时更新
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                updateLabel();  // 当内容删除时更新
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                updateLabel();  // 当内容改变时更新
            }

            // 更新 label 内容的方法
            private void updateLabel() {
                flowActions.setTransactionID(jTextFieldBankType.getText());
                performWriteAction();
            }
        });

        jTextFieldBankCode.getDocument().addDocumentListener(new DocumentListener() {
            @Override
            public void insertUpdate(DocumentEvent e) {
                updateLabel();  // 当内容插入时更新
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                updateLabel();  // 当内容删除时更新
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                updateLabel();  // 当内容改变时更新
            }

            // 更新 label 内容的方法
            private void updateLabel() {
                flowActions.setBankCode(jTextFieldBankCode.getText());
                performWriteAction();
            }
        });

        jTextFieldVersion.getDocument().addDocumentListener(new DocumentListener() {
            @Override
            public void insertUpdate(DocumentEvent e) {
                updateLabel();  // 当内容插入时更新
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                updateLabel();  // 当内容删除时更新
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                updateLabel();  // 当内容改变时更新
            }

            // 更新 label 内容的方法
            private void updateLabel() {
                flowActions.setVersion(jTextFieldVersion.getText());
                performWriteAction();
            }
        });

        jTextAreaDescription.getDocument().addDocumentListener(new DocumentListener() {
            @Override
            public void insertUpdate(DocumentEvent e) {
                updateLabel();  // 当内容插入时更新
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                updateLabel();  // 当内容删除时更新
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                updateLabel();  // 当内容改变时更新
            }

            // 更新 label 内容的方法
            private void updateLabel() {
                flowActions.setDescription(jTextAreaDescription.getText());
                performWriteAction();
            }
        });

    }


    private void loadFile() {
        try {
            String content = new String(file.contentsToByteArray(), StandardCharsets.UTF_8);
            // 解析 XML 并填充 actionConfigs
            parseActionsFromXml(content);
        } catch (IOException e) {
            LOG.error("Failed to load file: " + file.getName(), e);
        }
    }

    private void registerFileListener() {
        VirtualFileManager.getInstance().addVirtualFileListener(new CustomFileListener(this));
    }

    public VirtualFile getVirtualFile() {
        return this.file;
    }

    public void onFileContentChanged() {
        // 文件内容改变时调用的方法
        System.out.println("文件内容已改变！");
        // 在这里添加你需要执行的逻辑
        if (!isProgrammaticChange) loadFile();
    }

    public void refreshOriginalData() {
        // 遍历表格模型中的每一行数据
        for (int i = 0; i < tableModel.getRowCount(); i++) {
            String clazz = (String) tableModel.getValueAt(i, 0);
            boolean isSend = (Boolean) tableModel.getValueAt(i, 1);
            String configType = (String) tableModel.getValueAt(i, 2);

            // 创建一个新的 Action 对象
            Action action = actionConfigs.get(i);
            action.setClazz(clazz);
            action.setIsSend(isSend);
            // 假设 ActionConfig 类有一个 setType 方法
            action.getActionConfig().setType(configType);
        }
        // 保存文件以持久化更改
        performWriteAction();
    }


    private void parseActionsFromXml(String xmlContent)  {
        // 这里需要解析 XML 内容并填充 actionConfigs
        // 为了简化示例，我们手动添加一些动作
        try{
            actionConfigs.clear();
            flowActions = new XmlMapper().readValue(xmlContent, FlowActions.class);
            actionConfigs.addAll(flowActions.getActions());
        } catch (Exception e) {
            LOG.error("Failed to parse XML: " + xmlContent, e);
        }
        // 更新表格模型
        updateTableModel();
    }



    public void updateTableModel() {
        jTextFieldBankType.setText(flowActions.getTransactionID());
        jTextFieldBankCode.setText(flowActions.getBankCode());
        jTextFieldVersion.setText(flowActions.getVersion());
        jTextAreaDescription.setText(flowActions.getDescription());
        tableModel.setRowCount(0); // 清空现有数据
        for (com.wind.plugin.openAction.entity.Action config : actionConfigs) {
            tableModel.addRow(new Object[]{config.getClazz(), config.isIsSend(), config.getActionConfig().getType()});
        }
    }


    private void setUpUI() {

        actionsTable.getColumnModel().getColumn(1).setCellRenderer(new BooleanRenderer(new JCheckBox()));
        actionsTable.getColumnModel().getColumn(1).setCellEditor(new DefaultCellEditor(new JCheckBox()));

        // 添加编辑按钮列
        JButton editButton = new JButton("编辑");
        editButton.addActionListener(this::handleEditButtonClick);
        actionsTable.getColumn("编辑").setCellRenderer(new ButtonRenderer());
        actionsTable.getColumn("编辑").setCellEditor(new ButtonEditor(new JCheckBox(), editButton));

        // 创建表格面板
        JScrollPane tableScrollPane = new JBScrollPane(actionsTable);
        panel.add(tableScrollPane, BorderLayout.CENTER);
    }

    private void handleEditButtonClick(ActionEvent e) {
        int selectedRow = actionsTable.getSelectedRow();
        if (selectedRow >= 0) {
            com.wind.plugin.openAction.entity.Action config = actionConfigs.get(selectedRow);
            showEditDialog(config);
        }
    }

    private void showEditDialog(Action config) {
        EditorDialog dialog = new EditorDialog(project, config, this);
        dialog.show();
    }

    private void saveFile() {
        isProgrammaticChange = true;
        try {
            // 使用 XmlMapper 将 Java 对象转换为 XML 字符串
            XmlMapper xmlMapper = new XmlMapper();
            String xmlString = xmlMapper.writerWithDefaultPrettyPrinter().writeValueAsString(flowActions);
            // 格式化 Document 对象为字符串，并设置缩进
            file.setBinaryContent(Util.formatXml(xmlString).getBytes(StandardCharsets.UTF_8));
        } catch (IOException e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(null, "Error saving file", "Error", JOptionPane.ERROR_MESSAGE);
        } finally {
            isProgrammaticChange = false;
        }
    }

    public void performWriteAction() {
        Application application = ApplicationManager.getApplication();
        if (application.isDispatchThread()) {
            // 在 EDT 线程中
            application.runWriteAction(() -> {
                // 执行写操作
                // 例如：myFile.save();
                saveFile();
            });
        } else {
            // 不在 EDT 线程中
            application.invokeLater(() -> {
                application.runWriteAction(() -> {
                    // 执行写操作
                    // 例如：myFile.save();
                    saveFile();
                });
            });
        }
    }


    @Override
    public JComponent getComponent() {
        return panel;
    }

    @Override
    public JComponent getPreferredFocusedComponent() {
        return null;
    }

    @NotNull
    @Override
    public String getName() {
        return "XML图形化编辑";
    }

    @Override
    public void dispose() {
        // 清理资源
    }

    @Override
    public FileEditorLocation getCurrentLocation() {
        return null;
    }

    @Override
    public void setState(FileEditorState state) {
        // 处理编辑器状态
    }

    @Override
    public boolean isModified() {
        return false; // 你可以根据需要设置是否修改
    }

    @Override
    public boolean isValid() {
        return true;
    }

    @Override
    public void addPropertyChangeListener(@NotNull PropertyChangeListener propertyChangeListener) {

    }

    @Override
    public void removePropertyChangeListener(@NotNull PropertyChangeListener propertyChangeListener) {

    }

    @Nullable
    @Override
    public <T> T getUserData(@NotNull Key<T> key) {
        return null;
    }

    @Override
    public <T> void putUserData(@NotNull Key<T> key, @Nullable T t) {

    }



    private static class ButtonRenderer extends JButton implements TableCellRenderer {
        public ButtonRenderer() {
            setText("编辑");
            setOpaque(true);
        }

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            if (isSelected) {
                setBackground(table.getSelectionBackground());
            } else {
                setBackground(UIManager.getColor("Button.background"));
            }
            return this;
        }
    }

    private static class ButtonEditor extends DefaultCellEditor {

        private JButton button;

        public ButtonEditor(JCheckBox checkBox, JButton button) {
            super(checkBox);
            this.button = button;
        }

        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
            return button;
        }

        @Override
        public Object getCellEditorValue() {
            return null;
        }

        // 处理按钮按下时的操作
        public boolean stopCellEditing() {
            return super.stopCellEditing();
        }

        // 重写取消编辑方法
        protected void fireEditingStopped() {
            super.fireEditingStopped();
        }
    }

    private static class BooleanRenderer extends JCheckBox implements TableCellRenderer {
        private final JCheckBox checkBox;
        public BooleanRenderer(JCheckBox checkBox) {
            setHorizontalAlignment(SwingConstants.CENTER);
            this.checkBox = checkBox;
            checkBox.setHorizontalAlignment(SwingConstants.CENTER);
        }

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            setSelected(value != null && (Boolean) value);
            return this;
        }
    }
}
